package com.fy.opengltest.renderPolygn;

import android.content.Context;
import android.net.Uri;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;

import com.fy.opengltest.R;
import com.fy.opengltest.ShaderUtils;
import com.fy.opengltest.renderPicture.Circle2rectangle;
import com.fy.opengltest.renderPicture.TextureHelper;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

/**
 * Created by yao.fu on 17-1-23.
 */
public class GLRendererCircle2Rectangle implements GLSurfaceView.Renderer {

    private Context context;
    private Circle2rectangle mCircle;

    private Uri uri;

    private int programId;
    private int aPositionHandle;
    private int uMatrixHandle;

    private int textureId;
    private int uTextureSamplerHandle;
    private int aTextureCoordHandle;

    int screenWidth = 1;
    int screenHeight = 1;


    private float[] modelMatrix = new float[16];
    private float[] projectionMatrix = new float[16];
    private float[] viewMatrix = new float[16];
    private float[] modelViewMatrix = new float[16];
    private float[] mMVPMatrix = new float[16];


    public GLRendererCircle2Rectangle(Context context, Uri uri) {
        this.context = context;
        this.mCircle = new Circle2rectangle();
        this.uri = uri;
    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        String vertexShader = ShaderUtils.readRawTextFile(context, R.raw.vertex_shader_render_picture);
        String fragmentShader = ShaderUtils.readRawTextFile(context, R.raw.fragment_shader_render_picture);
        programId = ShaderUtils.createProgram(vertexShader, fragmentShader);
        aPositionHandle = GLES20.glGetAttribLocation(programId, "aPosition");
        uMatrixHandle = GLES20.glGetUniformLocation(programId, "uMatrix");

        if (null != uri)
            textureId = TextureHelper.loadTexture(context, uri);
        else
            textureId = TextureHelper.loadTexture(context, R.raw.dome190_24402400);//dome_pic640x480);//R.raw.demo_pic);

        uTextureSamplerHandle = GLES20.glGetUniformLocation(programId, "sTexture");
        aTextureCoordHandle = GLES20.glGetAttribLocation(programId, "aTexCoord");
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
//        BitmapFactory.Options options = new BitmapFactory.Options();
//        options.inJustDecodeBounds = true;
//        Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.test, options);
//        updateProjection(bitmap.getWidth(), bitmap.getHeight(), width, height);
//        bitmap.recycle();

        //updateProjection(9, 16, width, height);
//        updateProjection(480, 480, width, height);

        screenWidth = width;
        screenHeight = height;
        float ratio = (float) width / height;

//        /**
//         * Defines a projection matrix in terms of a field of view angle, an
//         * aspect ratio, and z clip planes.
//         *
//         * @param m the float array that holds the perspective matrix
//         * @param offset the offset into float array m where the perspective
//         *        matrix data is written
//         * @param fovy field of view in y direction, in degrees
//         * @param aspect width to height aspect ratio of the viewport
//         * @param zNear
//         * @param zFar
//         */
//        public static void perspectiveM(float[] m, int offset,
//                                        float fovy, float aspect, float zNear, float zFar) {


//        /**
//         * Defines a projection matrix in terms of six clip planes.
//         *
//         * @param m the float array that holds the output perspective matrix
//         * @param offset the offset into float array m where the perspective
//         *        matrix data is written
//         * @param left
//         * @param right
//         * @param bottom
//         * @param top
//         * @param near
//         * @param far
//         */
//    public static void frustumM(float[] m, int offset,
//                                float left, float right, float bottom, float top,
//                                float near, float far) {

        Matrix.frustumM(projectionMatrix, 0, -1f, 1f, 1f, -1f, 1f, 500f);

        Matrix.setLookAtM(viewMatrix, 0,
                0.0f, 0.0f, 1.0f,
                0.0f, 0.0f, 0f,
                0.0f, 1.0f, 0.0f);
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
        GLES20.glUseProgram(programId);

        Matrix.setIdentityM(modelMatrix, 0);
        Matrix.multiplyMM(modelViewMatrix, 0, viewMatrix, 0, modelMatrix, 0);
        Matrix.multiplyMM(mMVPMatrix, 0, projectionMatrix, 0, modelViewMatrix, 0);
        GLES20.glUniformMatrix4fv(uMatrixHandle, 1, false, mMVPMatrix, 0);

        mCircle.uploadVerticesBuffer(aPositionHandle);
        mCircle.uploadTexCoordinateBuffer(aTextureCoordHandle);

        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);

        GLES20.glUniform1i(uTextureSamplerHandle, 0);

        mCircle.draw();

    }

    private void updateProjection(int videoWidth, int videoHeight, int screenWidth, int screenHeight) {
        float screenRatio = (float) screenWidth / screenHeight;
        float videoRatio = (float) videoWidth / videoHeight;
        if (videoRatio > screenRatio) {
            Matrix.orthoM(projectionMatrix, 0, -1f, 1f, -videoRatio / screenRatio, videoRatio / screenRatio, -1f, 1f);
        } else
            Matrix.orthoM(projectionMatrix, 0, -screenRatio / videoRatio, screenRatio / videoRatio, -1f, 1f, -1f, 1f);
    }
}
